package com.service.infoEntry.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.service.config.utils.DateUtils;
import com.service.config.utils.IdUtil;
import com.service.config.utils.ModelMapperUtil;
import com.service.config.utils.Result;
import com.service.infoEntry.dao.TeamDao;
import com.service.infoEntry.dao.TeamUserDao;
import com.service.infoEntry.dto.TeamInfoDto;
import com.service.infoEntry.entity.*;
import com.service.infoEntry.service.RoleService;
import com.service.infoEntry.service.TeamService;
import com.service.infoEntry.service.UserInfoService;
import com.service.infoEntry.vo.RoleVo;
import com.service.infoEntry.vo.TeamVo;
import com.service.infoEntry.vo.UserVo;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.service.infoEntry.constant.Constant.*;

@Service
public class TeamServiceImpl implements TeamService {
    @Resource
    private TeamDao teamDao;
    @Resource
    private UserInfoService userInfoService;
    @Resource
    private TeamService teamService;
    @Resource
    private RoleService roleService;
    @Resource
    TeamUserDao teamUserDao;

    private final Integer PAGE_SIZE = 10;

    @Override
    public void createTeam(TeamInfoDto teamInfoDto,String creatorId) {
        TeamInfo teamInfo = ModelMapperUtil.strictMap(teamInfoDto, TeamInfo.class);
        String teamId = IdUtil.getStringId();
        teamInfo.setId(teamId);
        teamInfo.setAddTime(DateUtils.getNowDate());
        teamInfo.setStatus(0);
        teamInfo.setCreatorId(creatorId);
        teamInfo.setUpdateTime(DateUtils.getNowDate());
        teamDao.createTeam(teamInfo);
        teamDao.addUser2Team(IdUtil.getStringId(),teamInfo.getId(),creatorId,1,DateUtils.getNowDate(),DateUtils.getNowDate(),teamInfo.getCreatorId(),teamInfo.getCreatorId());
        UserInfo userInfo = userInfoService.queryById(creatorId);
        if(null == userInfo.getTeamId() || "".equals(userInfo.getTeamId()))
        {
            teamService.changeTeam(teamId,creatorId);
        }
    }

    /**
     *
     * @param teamId 团队id
     * @param userId 被添加用户name
     * @param adderId 添加人的id
     * @return
     */
    @Override
    public Result addUser2Team(String teamId, String userId, String adderId) {
        UserInfo userInfo = userInfoService.queryById(userId);
        //判断是否有该用户
        if(null == userInfo)
        {
            return Result.failure(USER_NOT_FOUND, "该用户不存在");
        }
        //判断该团队是否已经存在该用户
        int count = teamDao.findUserByTeamIdAndUserId(teamId, userInfo.getId());
        if(0 != count)
        {
            return Result.failure(USERNAME_REPEAT, "该团队已存在该用户");
        }
        teamDao.addUser2Team(IdUtil.getStringId(),teamId,userInfo.getId(),3,DateUtils.getNowDate(), DateUtils.getNowDate(),adderId,adderId);
        return Result.ok();
    }

    @Override
    public Result removeUserFromTeam(String teamId,Integer currentUserRole, String userId) {
        UserInfo userInfo = userInfoService.queryById(userId);
        //判断是否有该用户
        if(null == userInfo)
        {
            return Result.failure(USER_NOT_FOUND, "该用户不存在");
        }
        //判断该团队是否有该用户
        Integer count = teamDao.findUserByTeamIdAndUserId(teamId, userInfo.getId());
        if(count == 0)
        {
            return Result.failure(USERNAME_REPEAT, "该团队不存在该用户");
        }
        Integer role = teamDao.queryUserRole(userInfo.getId(), teamId);
        if(currentUserRole==1 && role == 1)
        {
            return Result.failure(USER_NO_AUTHORITY, "您当前权限为创建者，无法将自己移除");
        }else if(currentUserRole==2 && (role==1 || role == 2))
        {
            return Result.failure(USER_NO_AUTHORITY, "无法移除团队创建者或管理员");
        }
        teamDao.removeUserFromTeam(teamId,userInfo.getId());
        return Result.ok();
    }

    @Override
    public Result addAdminInTeam(String teamId, String userId) {
        UserInfo userInfo = userInfoService.queryById(userId);
        //判断是否有该用户
        if(null == userInfo)
        {
            return null;
        }
        //判断该团队是否有该用户
        Integer count = teamDao.findUserByTeamIdAndUserId(teamId, userInfo.getId());
        if(count == 0)
        {
            return Result.failure(USERNAME_REPEAT, "该团队不存在该用户!");
        }
        Integer role = teamDao.queryUserRole(userInfo.getId(), teamId);
        if(role == 2 || role == 1)
        {
            return Result.failure(USER_NO_AUTHORITY, "该用户已经是管理员用户!");
        }
        teamDao.addAdminInTeam(teamId,userInfo.getId());
        return Result.ok();
    }

    @Override
    public Result removeAdminInTeam(String teamId, String userId) {
        UserInfo userInfo = userInfoService.queryById(userId);
        //判断是否有该用户
        if(null == userInfo)
        {
            return null;
        }
        //判断该团队是否有该用户
        Integer count = teamDao.findUserByTeamIdAndUserId(teamId, userInfo.getId());
        if(count == 0)
        {
            return Result.failure(USERNAME_REPEAT, "该团队不存在该用户!");
        }
        Integer role = teamDao.queryUserRole(userInfo.getId(), teamId);
        if(role == 2)
        {
            teamDao.removeAdminInTeam(teamId,userInfo.getId());
            return Result.ok();
        }
        return Result.failure(USER_NOT_ADMIN,"该用户不是普通管理员用户");
    }

    @Override
    public Integer checkUserAuthority(String userId, String teamId) {
        Integer role = teamDao.queryUserRole(userId,teamId);
        return role;
    }

    @Override
    public List<TeamVo> queryTeamsWithRole(String userId) {
        List<TeamVo> teamVos = new ArrayList<>();
        List<TeamInfo> teamInfos = teamDao.queryTeamsByUserId(userId);
        if(null == teamInfos || teamInfos.size()<=0)
        {
            return null;
        }
        TeamVo teamVo;
        for (TeamInfo teamInfo : teamInfos) {
            RoleVo roleVo = roleService.queryRoleInTeam(teamInfo.getId(), userId);
            teamVo = new TeamVo();
            BeanUtils.copyProperties(teamInfo,teamVo);
            teamVo.setRole(roleVo);
            teamVos.add(teamVo);
        }
        return teamVos;
    }

    @Override
    public List<TeamInfo> queryTeams(String userId)
    {
        return teamDao.queryTeamsByUserId(userId);
    }

    @Override
    public Map<String,Object> queryAllUserInTeam(String teamId, String userId, Integer page) {
        Map<String,Object> map = new HashMap<>(16);
        PageHelper.startPage(page,PAGE_SIZE);
        List<UserInfo> userInfos = teamDao.queryAllUserInTeam(teamId);
        PageInfo<UserInfo> pageInfo = new PageInfo(userInfos);
        if(null==userInfos || userInfos.size()<=0)
        {
            return null;
        }
        List<UserVo> userVoList = new ArrayList<>();
        RoleVo roleVo;
        UserVo userVo;
        for (UserInfo userInfo : userInfos) {
            userVo = ModelMapperUtil.strictMap(userInfo,UserVo.class);
            roleVo = roleService.queryRoleInTeam(teamId,userInfo.getId());
            userVo.setRole(roleVo);
            if(userInfo.getId().equals(userId))
            {
                userVo.setCurrentUser(true);
            }else {
                userVo.setCurrentUser(false);
            }
            userVoList.add(userVo);
        }
        map.put("users",userVoList);
        map.put("pageSize",PAGE_SIZE);
        map.put("pageIndex",page);
        map.put("totalRecords",pageInfo.getTotal());
        map.put("totalPages",pageInfo.getPages());
        return map;
    }

    @Override
    public Result removeTeam(String teamId) {
        List<UserInfo> userInfos = teamDao.queryAllUserInTeam(teamId);
        teamDao.removeTeam(teamId);
        teamDao.removeAllUserFromTeam(teamId);

        List<TeamInfo> teamInfos;
        if(userInfos!=null && userInfos.size()>0)
        {
            for (UserInfo userInfo : userInfos) {
                if(userInfo.getTeamId().equals(teamId))
                {
                    teamInfos = teamDao.queryTeamsByUserId(userInfo.getId());
                    if(teamInfos!=null && teamInfos.size()>0 )
                    {
                        teamDao.changeTeam(teamInfos.get(0).getId(),userInfo.getId());
                    }else {
                        teamDao.changeTeam("",userInfo.getId());
                    }
                }
            }
        }
        return Result.ok();
    }

    @Override
    public Integer checkTeamIsExist(String teamId) {
        return teamDao.checkTeamIsExist(teamId);
    }

    /**
     * 管理员转移权限给普通用户
     * @param teamId 团队id
     * @param adminId 管理员id
     * @param userId 普通用户名
     * @return
     */
    @Override
    public Result changeAdmin(String teamId, String adminId, String userId) {
        UserInfo userInfo = userInfoService.queryById(userId);
        //判断是否有该用户
        if(null == userInfo)
        {
            return null;
        }
        //判断该团队是否有该用户
        Integer count = teamDao.findUserByTeamIdAndUserId(teamId, userInfo.getId());
        if(count == 0)
        {
            return Result.failure(USERNAME_REPEAT, "该团队不存在该用户!");
        }
        Integer role = teamDao.queryUserRole(userInfo.getId(), teamId);
        if(role == 3)
        {
            teamDao.addAdminInTeam(teamId,userInfo.getId());
            teamDao.removeAdminInTeam(teamId,adminId);
            return Result.ok();
        }
        return Result.failure(USER_NOT_ADMIN,"该用户不是普通用户");
    }

    @Override
    public Result exitTeam(String teamId, String userId) {
        teamDao.removeUserFromTeam(teamId,userId);
        List<TeamInfo> teamInfos = teamDao.queryTeamsByUserId(userId);
        UserInfo userInfo = userInfoService.queryById(userId);
        if(teamId.equals(userInfo.getTeamId()))
        {
            if(teamInfos!=null && teamInfos.size()>0)
            {
                teamDao.changeTeam(teamInfos.get(0).getId(),userId);
            }else {
                teamDao.changeTeam("",userId);
            }
        }
        return Result.ok();
    }

    @Override
    public RoleVo queryRoleInTeam(String userId, String teamId) {
        Role role = teamDao.queryRoleInTeam(userId,teamId);
        RoleVo roleVo = null;
        if(null != role)
        {
            roleVo = ModelMapperUtil.strictMap(role, RoleVo.class);
        }
        return roleVo;
    }

    @Override
    public RoleVo queryPermissionsInTeam(String teamId, String userId) {
        RoleVo roleVo;
        List<String> permissionNames = new ArrayList<>();
        RoleVo role = roleService.queryRoleInTeam(teamId,userId);
        List<Permission> permissions = teamDao.queryPermissionsInTeam(teamId, userId);
        if(role != null)
        {
            roleVo = ModelMapperUtil.strictMap(role, RoleVo.class);
            for (Permission permission : permissions) {
                permissionNames.add(permission.getPermissionName());
            }
            roleVo.setPermissions(permissions);
        }else {
            return null;
        }
        return roleVo;
    }

    @Override
    public TeamVo queryTeamByTeamId(String teamId) {
        TeamInfo teamInfo = teamDao.queryTeamByTeamId(teamId);
        if(null == teamInfo)
        {
            return null;
        }
        TeamVo teamVo = ModelMapperUtil.strictMap(teamInfo, TeamVo.class);
        return teamVo;
    }

    @Override
    public TeamVo changeTeam(String teamId, String userId) {
        teamDao.changeTeam(teamId,userId);
        TeamInfo teamInfo = teamDao.queryTeamByTeamId(teamId);
        TeamVo teamVo = ModelMapperUtil.strictMap(teamInfo,TeamVo.class);
        RoleVo roleVo = roleService.queryRoleInTeam(teamId, userId);
        teamVo.setRole(roleVo);
        return teamVo;
    }

    @Override
    public List<TeamInfo> queryAllTeam(TeamInfo teamInfo) {
        return teamDao.queryAllTeam(teamInfo);
    }

    @Override
    public List<TeamUser> queryAllUser() {
        return teamUserDao.queryAll(new TeamUser());
    }
}
